/*
 * Copyright (c) 2023 iQi.Co.Ltd. All rights reserved.
 */
 
using System.Collections.Generic;
using NetProtocol.POD;
using NetProtocol.Enum;
using IQIGame.Onigao.Game;
using IQIGame.Onigao.GamePlay;
using IQIGame.Onigao.Framework;
using Cysharp.Threading.Tasks;
using System;
using static IQIGame.Onigao.Game.MessageWrapper;

namespace NetProtocol.Client {
	/// <summary>
	/// 编队
	/// module : formation
	/// </summary>
	public interface CNetFormation : INetClientModule {
		
		public ISession GetSession();
	
		Dictionary<int, INetClientModule.Package2MessageWrapper> INetClientModule.GetModuleFunction()
        {
            MessageFunction notifyFormation_Delegate = (session, wrapper) =>
            {
            var _wrapper = (MessageWrapper<NotifyFormationData>)wrapper; 
#if ENABLE_NET_LOG || UNITY_EDITOR
            NetProtocolHelper.ClientLog(NetMessageId.formation_notifyFormation, "Recv->" + _wrapper.message.ToString());
#endif
                SC_notifyFormation(session, _wrapper.message.formationPOD);
                MessageWrapperPool<NotifyFormationData>.Put(_wrapper);
            };
            MessageFunction setCaptainResult_Delegate = (session, wrapper) =>
            {
            	var _wrapper = (MessageWrapper<SetCaptainResultData>)wrapper;
                SC_setCaptainResult(session, ref _wrapper.message);
                MessageWrapperPool<SetCaptainResultData>.Put(_wrapper);
            };
            MessageFunction setHeroResult_Delegate = (session, wrapper) =>
            {
            	var _wrapper = (MessageWrapper<SetHeroResultData>)wrapper;
                SC_setHeroResult(session, ref _wrapper.message);
                MessageWrapperPool<SetHeroResultData>.Put(_wrapper);
            };
            MessageFunction setFormNameResult_Delegate = (session, wrapper) =>
            {
            	var _wrapper = (MessageWrapper<SetFormNameResultData>)wrapper;
                SC_setFormNameResult(session, ref _wrapper.message);
                MessageWrapperPool<SetFormNameResultData>.Put(_wrapper);
            };
            MessageFunction setDefaultResult_Delegate = (session, wrapper) =>
            {
            	var _wrapper = (MessageWrapper<SetDefaultResultData>)wrapper;
                SC_setDefaultResult(session, ref _wrapper.message);
                MessageWrapperPool<SetDefaultResultData>.Put(_wrapper);
            };
        
            Dictionary<int, INetClientModule.Package2MessageWrapper> retDic = new()
            {
                {NetMessageId.formation_notifyFormation, (session, package) => {
                	var result = MessageWrapperPool<NotifyFormationData>.Get();
                	result.Init(session, notifyFormation_Delegate);
                	result.FromPackage(package);
                	return result;
                }},
                {NetMessageId.formation_setCaptainResult, (session, package) => {
                	var result = MessageWrapperPool<SetCaptainResultData>.Get();
                	result.Init(session, setCaptainResult_Delegate);
                	result.FromPackage(package);
                	return result;
                }},
                {NetMessageId.formation_setHeroResult, (session, package) => {
                	var result = MessageWrapperPool<SetHeroResultData>.Get();
                	result.Init(session, setHeroResult_Delegate);
                	result.FromPackage(package);
                	return result;
                }},
                {NetMessageId.formation_setFormNameResult, (session, package) => {
                	var result = MessageWrapperPool<SetFormNameResultData>.Get();
                	result.Init(session, setFormNameResult_Delegate);
                	result.FromPackage(package);
                	return result;
                }},
                {NetMessageId.formation_setDefaultResult, (session, package) => {
                	var result = MessageWrapperPool<SetDefaultResultData>.Get();
                	result.Init(session, setDefaultResult_Delegate);
                	result.FromPackage(package);
                	return result;
                }},
            };
            return retDic;
        }
#region Client-side Interface
		/// <summary>
        ///  更新编队，客户端只在这里更新数据，其它协议仅做展示；先更新数据，再通知结果
        /// </summary>
		protected void SC_notifyFormation(ISession session, FormationPOD formationPOD);
		/// <summary>
        ///  设置队长结果
        /// </summary>
		public void SC_setCaptainResult(ISession session, ref SetCaptainResultData message) 
		{
            _SC_setCaptainResult(session, ref message);
		}
		
		public void _SC_setCaptainResult(ISession session, ref SetCaptainResultData message)
		{
#if ENABLE_NET_LOG || UNITY_EDITOR
            NetProtocolHelper.ClientLog(NetMessageId.formation_setCaptainResult, "Recv->" + message.ToString());
#endif
			NetProtocolHelper.endCallRequest?.Invoke(NetMessageId.formation_setCaptainResult, message.code);
			MsgAsyncAwaiter<SetCaptainResultData>.Instance.CompleteMsgAwait(ref message);
		}
		
		/// <summary>
        ///  设置英雄结果
        /// </summary>
		public void SC_setHeroResult(ISession session, ref SetHeroResultData message) 
		{
            _SC_setHeroResult(session, ref message);
		}
		
		public void _SC_setHeroResult(ISession session, ref SetHeroResultData message)
		{
#if ENABLE_NET_LOG || UNITY_EDITOR
            NetProtocolHelper.ClientLog(NetMessageId.formation_setHeroResult, "Recv->" + message.ToString());
#endif
			NetProtocolHelper.endCallRequest?.Invoke(NetMessageId.formation_setHeroResult, message.code);
			MsgAsyncAwaiter<SetHeroResultData>.Instance.CompleteMsgAwait(ref message);
		}
		
		/// <summary>
        ///  设置编队名结果
        /// </summary>
		public void SC_setFormNameResult(ISession session, ref SetFormNameResultData message) 
		{
            _SC_setFormNameResult(session, ref message);
		}
		
		public void _SC_setFormNameResult(ISession session, ref SetFormNameResultData message)
		{
#if ENABLE_NET_LOG || UNITY_EDITOR
            NetProtocolHelper.ClientLog(NetMessageId.formation_setFormNameResult, "Recv->" + message.ToString());
#endif
			NetProtocolHelper.endCallRequest?.Invoke(NetMessageId.formation_setFormNameResult, message.code);
			MsgAsyncAwaiter<SetFormNameResultData>.Instance.CompleteMsgAwait(ref message);
		}
		
		/// <summary>
        ///  设置默认编队，成功时更新本地数据
        /// </summary>
		public void SC_setDefaultResult(ISession session, ref SetDefaultResultData message) 
		{
            _SC_setDefaultResult(session, ref message);
		}
		
		public void _SC_setDefaultResult(ISession session, ref SetDefaultResultData message)
		{
#if ENABLE_NET_LOG || UNITY_EDITOR
            NetProtocolHelper.ClientLog(NetMessageId.formation_setDefaultResult, "Recv->" + message.ToString());
#endif
			NetProtocolHelper.endCallRequest?.Invoke(NetMessageId.formation_setDefaultResult, message.code);
			MsgAsyncAwaiter<SetDefaultResultData>.Instance.CompleteMsgAwait(ref message);
		}
		
#endregion
#region Server-side Interface
		/// <summary>
        ///  设置队长
        /// </summary>
    	public UniTask<SetCaptainResultData> CS_setCaptain(int formId, int heroCid)
        {
            return _CS_setCaptain(formId, heroCid);
        }
        
        public UniTask<SetCaptainResultData> _CS_setCaptain(int formId, int heroCid)
        {
        	ISession session = GetSession();
        	if(session == null) return UniTask.FromResult(default(SetCaptainResultData));
#if ENABLE_NET_LOG || UNITY_EDITOR
			NetProtocolHelper.ClientLog(NetMessageId.formation_setCaptain, "Send->"+"Formation.CS_setCaptain { "
				+ "formId="
				+ formId
				+ ", heroCid="
				+ heroCid
				+" }");
#endif
        	UniTask<SetCaptainResultData> task = MsgAsyncAwaiter<SetCaptainResultData>.Instance.AddMsgAwait();
        	session.SendPack(Pack_for_setCaptain(formId, heroCid));
        	NetProtocolHelper.beginCallRequest?.Invoke(NetMessageId.formation_setCaptainResult);
			return task;
        }
		
		public static SendPackage Pack_for_setCaptain(int formId, int heroCid) 
		{
			SendPackage si_p = NetProtocolHelper.GetSendPackage();
			si_p.Header.Messagid = NetMessageId.formation_setCaptain;
			si_p.StartWrite();
			SOutputStream _out = si_p.OutputStream;
			_out.Write_int(formId);
			_out.Write_int(heroCid);
			return si_p;
		}
		/// <summary>
        ///  设置英雄 -- heroCid为0表示下阵
        /// </summary>
    	public UniTask<SetHeroResultData> CS_setHero(int formId, int pos, int heroCid)
        {
            return _CS_setHero(formId, pos, heroCid);
        }
        
        public UniTask<SetHeroResultData> _CS_setHero(int formId, int pos, int heroCid)
        {
        	ISession session = GetSession();
        	if(session == null) return UniTask.FromResult(default(SetHeroResultData));
#if ENABLE_NET_LOG || UNITY_EDITOR
			NetProtocolHelper.ClientLog(NetMessageId.formation_setHero, "Send->"+"Formation.CS_setHero { "
				+ "formId="
				+ formId
				+ ", pos="
				+ pos
				+ ", heroCid="
				+ heroCid
				+" }");
#endif
        	UniTask<SetHeroResultData> task = MsgAsyncAwaiter<SetHeroResultData>.Instance.AddMsgAwait();
        	session.SendPack(Pack_for_setHero(formId, pos, heroCid));
        	NetProtocolHelper.beginCallRequest?.Invoke(NetMessageId.formation_setHeroResult);
			return task;
        }
		
		public static SendPackage Pack_for_setHero(int formId, int pos, int heroCid) 
		{
			SendPackage si_p = NetProtocolHelper.GetSendPackage();
			si_p.Header.Messagid = NetMessageId.formation_setHero;
			si_p.StartWrite();
			SOutputStream _out = si_p.OutputStream;
			_out.Write_int(formId);
			_out.Write_int(pos);
			_out.Write_int(heroCid);
			return si_p;
		}
		/// <summary>
        ///  设置编队名
        /// </summary>
    	public UniTask<SetFormNameResultData> CS_setFormName(int formId, string name)
        {
            return _CS_setFormName(formId, name);
        }
        
        public UniTask<SetFormNameResultData> _CS_setFormName(int formId, string name)
        {
        	ISession session = GetSession();
        	if(session == null) return UniTask.FromResult(default(SetFormNameResultData));
#if ENABLE_NET_LOG || UNITY_EDITOR
			NetProtocolHelper.ClientLog(NetMessageId.formation_setFormName, "Send->"+"Formation.CS_setFormName { "
				+ "formId="
				+ formId
				+ ", name="
				+ name
				+" }");
#endif
        	UniTask<SetFormNameResultData> task = MsgAsyncAwaiter<SetFormNameResultData>.Instance.AddMsgAwait();
        	session.SendPack(Pack_for_setFormName(formId, name));
        	NetProtocolHelper.beginCallRequest?.Invoke(NetMessageId.formation_setFormNameResult);
			return task;
        }
		
		public static SendPackage Pack_for_setFormName(int formId, string name) 
		{
			SendPackage si_p = NetProtocolHelper.GetSendPackage();
			si_p.Header.Messagid = NetMessageId.formation_setFormName;
			si_p.StartWrite();
			SOutputStream _out = si_p.OutputStream;
			_out.Write_int(formId);
			_out.Write_string(name);
			return si_p;
		}
		/// <summary>
        ///  设置默认编队
        /// </summary>
    	public UniTask<SetDefaultResultData> CS_setDefault(int formId)
        {
            return _CS_setDefault(formId);
        }
        
        public UniTask<SetDefaultResultData> _CS_setDefault(int formId)
        {
        	ISession session = GetSession();
        	if(session == null) return UniTask.FromResult(default(SetDefaultResultData));
#if ENABLE_NET_LOG || UNITY_EDITOR
			NetProtocolHelper.ClientLog(NetMessageId.formation_setDefault, "Send->"+"Formation.CS_setDefault { "
				+ "formId="
				+ formId
				+" }");
#endif
        	UniTask<SetDefaultResultData> task = MsgAsyncAwaiter<SetDefaultResultData>.Instance.AddMsgAwait();
        	session.SendPack(Pack_for_setDefault(formId));
        	NetProtocolHelper.beginCallRequest?.Invoke(NetMessageId.formation_setDefaultResult);
			return task;
        }
		
		public static SendPackage Pack_for_setDefault(int formId) 
		{
			SendPackage si_p = NetProtocolHelper.GetSendPackage();
			si_p.Header.Messagid = NetMessageId.formation_setDefault;
			si_p.StartWrite();
			SOutputStream _out = si_p.OutputStream;
			_out.Write_int(formId);
			return si_p;
		}
#endregion
#region Messages
        public struct NotifyFormationData : IReceiveMessage {
	        public FormationPOD formationPOD;
            public void FromPackage(ReceivePackage _package)
            {
                SInputStream _in = _package.InputStream;
                formationPOD = _in.HasRemaining() ? _in.Read_pod<FormationPOD>(FormationPOD.DynamicFactory) : default;
            }
            
            public int GetMessageId() {return NetMessageId.formation_notifyFormation;}
            
            public override string ToString()
            {
                return "Formation.notifyFormation"+ ", formationPOD="+ formationPOD;
            }
        }
        public struct SetCaptainResultData : IReceiveMessage {
        	private int? _code;
        	public int code {get{return _code == null ? -1 : (int)_code;}private set{_code = value;}}
            public bool IsFail => _code != null && _code != 0;
            public bool IsSuccess =>_code != null && _code == 0;
            public bool IsCanceled => _code == null;
            public void FromPackage(ReceivePackage _package)
            {
                SInputStream _in = _package.InputStream;
                code = _in.HasRemaining() ? _in.Read_int() : default;
            }
            
            public int GetMessageId() {return NetMessageId.formation_setCaptainResult;}
            
            public override string ToString()
            {
                return "Formation.setCaptainResult"+ ", code="+ code;
            }
        }
        public struct SetHeroResultData : IReceiveMessage {
        	private int? _code;
        	public int code {get{return _code == null ? -1 : (int)_code;}private set{_code = value;}}
            public bool IsFail => _code != null && _code != 0;
            public bool IsSuccess =>_code != null && _code == 0;
            public bool IsCanceled => _code == null;
            public void FromPackage(ReceivePackage _package)
            {
                SInputStream _in = _package.InputStream;
                code = _in.HasRemaining() ? _in.Read_int() : default;
            }
            
            public int GetMessageId() {return NetMessageId.formation_setHeroResult;}
            
            public override string ToString()
            {
                return "Formation.setHeroResult"+ ", code="+ code;
            }
        }
        public struct SetFormNameResultData : IReceiveMessage {
        	private int? _code;
        	public int code {get{return _code == null ? -1 : (int)_code;}private set{_code = value;}}
            public bool IsFail => _code != null && _code != 0;
            public bool IsSuccess =>_code != null && _code == 0;
            public bool IsCanceled => _code == null;
            public void FromPackage(ReceivePackage _package)
            {
                SInputStream _in = _package.InputStream;
                code = _in.HasRemaining() ? _in.Read_int() : default;
            }
            
            public int GetMessageId() {return NetMessageId.formation_setFormNameResult;}
            
            public override string ToString()
            {
                return "Formation.setFormNameResult"+ ", code="+ code;
            }
        }
        public struct SetDefaultResultData : IReceiveMessage {
        	private int? _code;
        	public int code {get{return _code == null ? -1 : (int)_code;}private set{_code = value;}}
	        public int formId;
            public bool IsFail => _code != null && _code != 0;
            public bool IsSuccess =>_code != null && _code == 0;
            public bool IsCanceled => _code == null;
            public void FromPackage(ReceivePackage _package)
            {
                SInputStream _in = _package.InputStream;
                code = _in.HasRemaining() ? _in.Read_int() : default;
                formId = _in.HasRemaining() ? _in.Read_int() : default;
            }
            
            public int GetMessageId() {return NetMessageId.formation_setDefaultResult;}
            
            public override string ToString()
            {
                return "Formation.setDefaultResult"+ ", code="+ code+ ", formId="+ formId;
            }
        }
    }
#endregion
}